package com.fly.snailrun.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileCopier;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.fly.snailrun.base.config.JianYingConfig;
import com.fly.snailrun.base.constant.JianYinConstant;
import com.fly.snailrun.base.constant.SuffixConstant;
import com.fly.snailrun.domain.dto.DraftMaterials;
import com.fly.snailrun.domain.dto.DraftMaterialsValue;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class JianYinUtil {
    public static final String PATH_SPLIT = "/";
    private static final JianYingConfig properties = SpringUtil.getBean(JianYingConfig.class);

    public static String getDraftMetaInfoPath(String directory, String draftName) {
        return directory + PATH_SPLIT + draftName + PATH_SPLIT + JianYinConstant.DRAFT_META_INFO + SuffixConstant.JSON;
    }

    public static String getDraftContentPath(String directory, String draftName) {
        return directory + PATH_SPLIT + draftName + PATH_SPLIT + JianYinConstant.DRAFT_CONTENT + SuffixConstant.JSON;
    }

    public static String getDraftMetaInfoPath() {
        return getDraftMetaInfoPath(properties.getDirectory(), properties.getName());
    }

    public static String getDraftContentPath() {
        return getDraftContentPath(properties.getDirectory(), properties.getName());
    }

    public static String getDraftContentPath(String draftName) {
        return getDraftContentPath(properties.getDirectory(), draftName);
    }

    public static JSONObject getDraftMetaInfo() {
        String draftMetaInfoPath = getDraftMetaInfoPath();
        String jsonStr = FileUtil.readUtf8String(draftMetaInfoPath);
        return JSONObject.parseObject(jsonStr);
    }

    public static DraftMaterials getDraftMaterials() {
        String draftMetaInfoPath = getDraftMetaInfoPath();
        String jsonStr = FileUtil.readUtf8String(draftMetaInfoPath);
        return JSONObject.parseObject(jsonStr, DraftMaterials.class);
    }

    public static DraftMaterialsValue getDraftMaterialsValue(Integer type) {
        for (DraftMaterialsValue draftMaterialsValue : getDraftMaterials().getValue()) {
            if (JianYinConstant.DRAFT_MATERIALS_TYPE.equals(type)) {
                return draftMaterialsValue;
            }
        }
        return null;
    }

    public static JSONObject getDraftContent() {
        String draftContentPath = getDraftContentPath();
        String read = FileUtil.readUtf8String(draftContentPath);
        return JSONObject.parseObject(read);
    }

    public static JSONObject getDraftContent(String draftName) {
        String draftContentPath = getDraftContentPath(properties.getDirectory(), draftName);
        String read = FileUtil.readUtf8String(draftContentPath);
        return JSONObject.parseObject(read);
    }

    public static void write(String content) {
        FileUtil.writeUtf8String(content, getDraftMetaInfoPath());
    }

    public static String getPath(String... directory) {
        StringBuilder path = new StringBuilder();
        for (int i = 0; i < directory.length; i++) {
            if (i < directory.length - 1) {
                path.append(directory[i]).append(PATH_SPLIT);
            } else {
                path.append(directory[i]);
            }
        }
        return path.toString();
    }

    public static String getId() {
        return UUID.randomUUID().toString();
    }

    public static Long getRandomSplit() {
        Integer splitMin = properties.getSplitMin();
        Integer splitMax = properties.getSplitMax();
        int i = RandomUtil.randomInt(splitMin, splitMax);
        return i * 1000 * 1000L;
    }

    public static Long getRandomSplit(Integer splitMin, Integer splitMax) {
        int i = RandomUtil.randomInt(splitMin, splitMax);
        return i * 1000 * 1000L;
    }

    public static Double getRandomSpeed() {
        Double speedMin = properties.getSpeedMin();
        Double speedMax = properties.getSpeedMax();
        return speedMax.equals(speedMin) ? speedMin : RandomUtil.randomDouble(speedMin, speedMax, 1, RoundingMode.HALF_UP);
    }

    public static Double getRandomSpeed(Double speedMin, Double speedMax) {
        return speedMax.equals(speedMin) ? speedMin : RandomUtil.randomDouble(speedMin, speedMax, 1, RoundingMode.HALF_UP);
    }

    public static Integer getRandomRange() {
        Integer videoMin = properties.getVideoMin();
        Integer videoMax = properties.getVideoMax();
        if (Objects.equals(videoMax, videoMin)) {
            return videoMin;
        }
        return RandomUtil.randomInt(videoMin, videoMax);
    }

    public static Integer getRandomRange(Integer videoMin, Integer videoMax) {
        if (Objects.equals(videoMax, videoMin)) {
            return videoMin;
        }
        return RandomUtil.randomInt(videoMin, videoMax);
    }

    public static Integer getRandomBlur() {
        Integer blurMin = properties.getBlurMin();
        Integer blurMax = properties.getBlurMax();
        return blurMin.equals(blurMax) ? blurMax : RandomUtil.randomInt(blurMin, blurMax);
    }

    public static Integer getRandomBlur(Integer blurMin, Integer blurMax) {
        return blurMin.equals(blurMax) ? blurMax : RandomUtil.randomInt(blurMin, blurMax);
    }

    public static List<String> getAllFiles() {
        String file = properties.getFile();
        return FileUtil.listFileNames(file)
                .stream()
                .map(item -> file + "/" + item)
                .filter(item -> item.endsWith(".mp4"))
                .collect(Collectors.toList());
    }

    public static List<String> createDraftFile(Integer draftNum, String draftTemplateName) {
        String directory = properties.getDirectory();
        String name;
        if (StringUtils.isEmpty(draftTemplateName)) {
            name = properties.getName();
        } else {
            name = draftTemplateName;
        }
        String draftDirectory = directory + "/" + name;
        List<String> draftFilePath = new ArrayList<>();
        List<String> fileNames = Arrays.stream(FileUtil.ls(directory)).map(file -> file.getName()).collect(Collectors.toList());
        int index = 0;
        int i = 0;
        while (i < draftNum) {
            String copyFileName = name + "_snail_" + index;
            String copyDraftPath = directory + "/" + copyFileName;
            if (fileNames.contains(copyFileName)) {
                index++;
                continue;
            }
            FileCopier.create(draftDirectory, copyDraftPath).setCopyContentIfDir(true).copy();
            draftFilePath.add(copyFileName);
            i++;
            index++;
        }
        return draftFilePath;
    }

    public static List<String> createDraftFile(Integer draftNum, String draftFileName, String draftTemplateName) {
        String directory = properties.getDirectory();
        String name;
        if (StringUtils.isEmpty(draftTemplateName)) {
            name = properties.getName();
        } else {
            name = draftTemplateName;
        }
        String draftDirectory = directory + "/" + name;
        List<String> draftFilePath = new ArrayList<>();
        List<String> fileNames = Arrays.stream(FileUtil.ls(directory)).map(file -> file.getName()).collect(Collectors.toList());
        int index = 0;
        int i = 0;
        while (i < draftNum) {
            String copyFileName = name + "_" + draftFileName + "_" + index;
            String copyDraftPath = directory + "/" + copyFileName;
            if (fileNames.contains(copyFileName)) {
                index++;
                continue;
            }
            FileCopier.create(draftDirectory, copyDraftPath).setCopyContentIfDir(true).copy();
            draftFilePath.add(copyFileName);
            i++;
            index++;
        }
        return draftFilePath;
    }

    public static double getRandomXLocation() {
        Integer locationXMax = properties.getLocationXMax();
        Integer locationXMin = properties.getLocationXMin();
        return (Objects.equals(locationXMin, locationXMax) ? locationXMin : RandomUtil.randomInt(locationXMin, locationXMax, true, true)) * 0.000925925925925926;

    }

    public static double getRandomYLocation() {
        Integer locationYMax = properties.getLocationYMax();
        Integer locationYMin = properties.getLocationYMin();
        return (Objects.equals(locationYMin, locationYMax) ? locationYMin : RandomUtil.randomInt(locationYMin, locationYMax, true, true)) * 0.0005208333333333333;
    }

    public static double getRandomScale() {
        Integer scaleMin = properties.getScaleMin();
        Integer scaleMax = properties.getScaleMax();
        return (Objects.equals(scaleMin, scaleMax) ? scaleMax : RandomUtil.randomInt(scaleMin, scaleMax, true, true));
    }
}
